package com.ruoyi.system.service.impl;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.MktPeople;
import com.ruoyi.system.domain.MktStatistics;
import com.ruoyi.system.mapper.MktPeopleMapper;
import com.ruoyi.system.service.IMktStatisticsService;
import com.ruoyi.system.domain.vo.MktTaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.mapper.MktTaskMapper;
import com.ruoyi.system.domain.MktTask;
import com.ruoyi.system.service.IMktTaskService;


@Service
public class MktTaskServiceImpl extends ServiceImpl<MktTaskMapper, MktTask> implements IMktTaskService {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private MktPeopleMapper mktPeopleMapper;
    @Autowired
    private IMktStatisticsService MktStatisticsService;

    /**
     * 查询营销任务管理列表
     *
     * @param mktTask 营销任务管理
     * @return 营销任务管理
     */
    @Override
    public List<MktTask> selectMktTaskList(MktTask mktTask) {
        return getBaseMapper().selectMktTaskList(mktTask);
    }

    @Override
    public List<MktTask> getTaskToDo(Long actId, LoginUser loginUser) {

        //创建一个任务集合
        List<MktTask> mktTaskList = new ArrayList<>();

        //通过活动的id在查询出该活动的所有任务
        LambdaQueryWrapper<MktTask> queryWrapper = new LambdaQueryWrapper<MktTask>()
                .eq(MktTask::getActId, actId);
        List<MktTask> mktTasks = super.list(queryWrapper);
        //拿到用户的创建时间
        SysUser user = loginUser.getUser();
        Date createTime = user.getCreateTime();
        LocalDateTime dateTime = LocalDateTime.of(createTime.getYear(), createTime.getMonth(), createTime.getMonth(), createTime.getDay(), createTime.getMinutes(), createTime.getSeconds());
        LocalDateTime now = LocalDateTime.now();
        //获取当前时间和用户创建时间的差
        Duration duration = Duration.between(dateTime, now);
        long seconds = duration.getSeconds();
        //30天有2592000秒
        //遍历任务
        for (MktTask mktTask : mktTasks) {
            //用户限制
            switch (mktTask.getParticipationRestriction()){
                //新用户
                case 0 :
                {
                    if (seconds < 2592000){
                        //满足新用户的条件
                        //再判断任务是每日任务还是一次性任务
                        // 0 限制一次 1 每日刷新
                        determineTaskType(mktTaskList, user, mktTask);
                    }
                    break;
                }
                //老用户
                case 1 :
                {
                    if (seconds > 2592000){
                        //满足老用户的条件
                        //再判断任务是每日任务还是一次性任务
                        // 0 限制一次 1 每日刷新
                        determineTaskType(mktTaskList, user, mktTask);
                    }
                    break;
                }
                //全部用户
                default:
                {
                    // 0 限制一次 1 每日刷新
                    determineTaskType(mktTaskList, user, mktTask);
                }
            }
        }
        return mktTaskList;
    }

    @Override
    public void finishTask(Long taskId, LoginUser loginUser) {
        //拿到当前用户信息
        SysUser user = loginUser.getUser();
        //通过任务id来查询出任务,根据查询出来的任务类型,选择不同的完成任务方式
        //查询任务
        MktTask mktTask = super.getById(taskId);
        //对任务对象进行判断 0 表示为限制一次  1 表示每日任务
        if (mktTask.getFrequencyLimit()==0){
            //如果是一次性任务就需要去修改数据库里面的状态
            getBaseMapper().updateByTaskIdAndPid(mktTask.getId(),user.getUserId());

            //完成任务就需要使得奖励加1
            //在用户的数据库中查询根据当前用户的id来查询出对象集合
            increaseRaffle(user, mktTask);


        }else if (mktTask.getFrequencyLimit() == 1){
            String key = "mkt:task:"+mktTask.getId();
            //每日任务,就需要使用redis进行处理
            //往redis中存入数据
            redisCache.sAdd(key,user.getUserId());
            //查看过期时间
            Long ttl = redisCache.ttl(key);
            if (ttl < 0){
                //如果小于0那么就是说今天第一次设置过期时间
                LocalDateTime startTime = LocalDateTime.now();
                LocalDateTime endTime = LocalDateTime.of(startTime.getYear(), startTime.getMonth(), startTime.getDayOfMonth(),
                        23, 59, 59);
                Duration duration = Duration.between(startTime, endTime);
                //再为key设置过期时间
                redisCache.expire(key,duration.toNanos(), TimeUnit.NANOSECONDS);
            }
            //完成任务就需要使得奖励加1
            //在用户的数据库中查询根据当前用户的id来查询出对象集合
            increaseRaffle(user, mktTask);

        }

    }

    private void increaseRaffle(SysUser user, MktTask mktTask) {
        List<MktPeople> mktPeoples = mktPeopleMapper.selectList(new LambdaQueryWrapper<MktPeople>()
                .eq(MktPeople::getUserId, user.getUserId()));
        //如果这集合为空那么就直接mktPeople对象
        if (mktPeoples.size() == 0) {
            MktPeople mktPeople = new MktPeople();
            mktPeople.setUserId(user.getUserId());
            mktPeople.setName(user.getNickName());
            mktPeople.setPhone(Long.valueOf(user.getPhonenumber()));
            mktPeople.setSurplusDraw(0);
            mktPeople.setWinNum(0);
            mktPeopleMapper.insert(mktPeople);
            //也需要在关系表中添加
            mktPeopleMapper.insertStatisticsPeople(mktTask.getActId(), mktPeople.getId());
        }

        int count = 0;
        //如果不为空,那么就遍历这个集合
        for (MktPeople mktPeople : mktPeoples) {
            //判断当前用户是否参与该活动
            Long activityId = mktPeopleMapper.isJoinActivity(mktPeople.getId());
            //判断activityId是否为活动的id
            if (mktTask.getActId().equals(activityId)) {
                //如果相等,那么就说明该用户不是第一次参与该活动,就不用再创建
                //增加抽奖次
                mktPeople.setSurplusDraw(mktPeople.getSurplusDraw() + 1);
                //修改
                mktPeopleMapper.updateById(mktPeople);
                count++;
            }
        }
        //如果没得那么就需要新增
        if (count == 0) {
            //说明需要新增
            MktPeople mktPeople = new MktPeople();
            mktPeople.setUserId(user.getUserId());
            mktPeople.setName(user.getNickName());
            mktPeople.setPhone(Long.valueOf(user.getPhonenumber()));
            mktPeople.setSurplusDraw(1);
            mktPeople.setWinNum(0);
            mktPeopleMapper.insert(mktPeople);
            //在关系表中新增
            mktPeopleMapper.insertStatisticsPeople(mktTask.getActId(), mktPeople.getId());
            //如果完成任务新增对象,那么就说明该活动增加1人
            MktStatistics mktStatistics = MktStatisticsService
                    .getOne(new LambdaQueryWrapper<MktStatistics>().eq(MktStatistics::getId, mktTask.getActId()));

            //将参与人数+1
            mktStatistics.setPeopleNum(mktStatistics.getPeopleNum()+1);
            MktStatisticsService.updateById(mktStatistics);
        }
    }

    private void determineTaskType(List<MktTask> mktTaskList, SysUser user, MktTask mktTask) {
        if (mktTask.getFrequencyLimit() == 0){
            //需要先在任务和参与人中表中去查询
            MktTaskVo mktTaskVo= getBaseMapper().selectTaskToDo(mktTask.getId(),user.getUserId());
            //通过查询出来的结果,判断当前用户是做过该任务
            if (mktTaskVo == null){
                //没查询出结果,那么就是该用户没完成过这个一次性任务,就需要将该任务加入待完成任务集合中
                mktTaskList.add(mktTask);
                //并且将一次性任务存入表中,状态为0
                getBaseMapper().insertTaskPeople(mktTask.getId(),user.getUserId());
            }else {
                //查询出结果,那么就判断他的状态status是否为0,为0才将这个任务放入待完成的任务集合中
                //判断status是否为0
                if (mktTaskVo.getStatus() == 0){
                    //等于0才将任务放在待完成任务集合
                    mktTaskList.add(mktTask);
                }
            }
        }else if (mktTask.getFrequencyLimit() == 1){
            //如果是每日任务我就把他放在redis中,我们去redis查询,并且为redis设置过期时间
            String key = "mkt:task:"+mktTask.getId();
            //如果在集合中,那么就是每日任务就完成了的
            Boolean member = redisCache.isMember(key, user.getUserId());
            //判断集合中是否有该对象
            if (!member){
                //不存在的时候
                //如果没有在集合中,就说明该每日任务没有完成,就将这个任务放入待完成任务集合中
                mktTaskList.add(mktTask);
            }
            //使用redis的set数据类型,并设置过期时间,任务的id作为key,用户的id作为集合
        }
    }
}